package net.gdface.json;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import net.gdface.annotations.ActiveOnClass;
/**
 * @author guyadong
 * @since 2.7.0
 */
@ActiveOnClass(ObjectMapper.class)
public class JacksonSupport extends JsonSupport{
	private final ObjectMapper deserializeMapper = new ObjectMapper();
	private final ObjectMapper serializeIndentMapper = new ObjectMapper().configure( SerializationFeature.INDENT_OUTPUT, true );
	private final ObjectMapper serializeMapper = new ObjectMapper().configure( SerializationFeature.INDENT_OUTPUT, false );
	@Override
	public String toJSONString(Object object, boolean prettyFormat) throws JsonSupportException{
		ObjectMapper mapper = prettyFormat ? serializeIndentMapper : serializeMapper;
		try {
			return mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			throw new JsonSupportException(e);
		}
	}
	@Override
	public Object parseOrEmptyMap(String json) throws JsonSupportException{
		try {
			if(null == json || 0 == json.length()){
				return new LinkedHashMap<>();
			}
			switch (maybeJsonString(json)) {
			case 1:
				return deserializeMapper.readValue(json,LinkedHashMap.class);
			case 2:
				return deserializeMapper.readValue(json,LinkedList.class);
			default:
				throw new JsonSupportException("NONE A JSON :" + json);
			}
		} catch (JsonProcessingException e) {
			throw new JsonSupportException(e);
		} catch (IOException e) {
			throw new JsonSupportException(e);
		} 
	}
	@Override
	public <T> T parse(String json, Class<T> targetType) throws JsonSupportException {
		if(null == json || 0 == json.length()){
			return null;
		}
		try {
			return deserializeMapper.readValue(json, targetType);
		} catch (JsonProcessingException e) {
			throw new JsonSupportException(e);
		} catch (IOException e) {
			throw new JsonSupportException(e);
		}
	}
	/**
	 * 判断对象是否有可能是JSON 字符串,
	 * 如果是String类型且前后以{}返回1
	 * 如果是String类型且前后以[]返回2
	 * 否则返回0
	 * @param object
	 */
	private static int maybeJsonString(Object object){
		if(object instanceof String){
			String s = (String)object;
			if(s.length() > 1){
				if(s.charAt(0) == '{' && s.charAt(s.length()-1)=='}'){
					return 1;
				}
				if(s.charAt(0) == '[' && s.charAt(s.length()-1)==']'){
					return 2;
				}
			}
		}
		return 0;
	}
}
